﻿namespace YunQue.Common.Helpers
{
    /// <summary>
    /// 日志帮助类
    /// </summary>
    public class LogHelper
    {
        private readonly ILogger<LogHelper> _logger = null;
        private readonly IServiceScopeFactory _serviceScopeFactory;
        /// <summary>
        /// 日志帮助类
        /// </summary>
        /// <param name="serviceScopeFactory"></param>
        public LogHelper(IServiceScopeFactory serviceScopeFactory)
        {
            _logger = serviceScopeFactory.CreateScope().ServiceProvider.GetRequiredService<ILogger<LogHelper>>();
            _serviceScopeFactory = serviceScopeFactory;
        }
        /// <summary>
        /// Info
        /// </summary>
        /// <param name="message"></param>
        /// <param name="objs"></param>
        public void LogInformation(string message, params KeyValuePair<string, object>[] objs)
        {
            objs = AddOtherInfo(objs);
            _logger.LogInformation(message, objs);
        }
        /// <summary>
        /// Error
        /// </summary>
        /// <param name="message"></param>
        /// <param name="objs"></param>
        public void LogError(string message, params KeyValuePair<string, object>[] objs)
        {
            objs = AddOtherInfo(objs);
            _logger.LogError(message, objs);
        }
        /// <summary>
        /// Error
        /// </summary>
        /// <param name="message"></param>
        /// <param name="e"></param>
        /// <param name="objs"></param>
        public void LogError(string message, Exception e, params KeyValuePair<string, object>[] objs)
        {
            objs = AddOtherInfo(objs);
            _logger.LogError(message, e, objs);
        }
        /// <summary>
        /// Warn
        /// </summary>
        /// <param name="message"></param>
        /// <param name="objs"></param>
        public void LogWarning(string message, params KeyValuePair<string, object>[] objs)
        {
            objs = AddOtherInfo(objs);
            _logger.LogWarning(message, objs);
        }
        /// <summary>
        /// 添加TranceId
        /// </summary>
        /// <param name="objs"></param>
        /// <returns></returns>
        private KeyValuePair<string, object>[] AddOtherInfo(KeyValuePair<string, object>[] objs)
        {
            if (objs == null) objs = new KeyValuePair<string, object>[3];
            if (_serviceScopeFactory == null) return objs;
            using (var scope = _serviceScopeFactory.CreateScope())
            {
                var httpContextAccessor = scope.ServiceProvider.GetService<IHttpContextAccessor>();
                var httpContext = httpContextAccessor?.HttpContext;
                string traceId = string.Empty, userId = string.Empty, remoteIp = string.Empty;
                if (httpContext != null)
                {
                    traceId = httpContext.Request.Headers[AppSettingManager.TRANCEID];
                    if (string.IsNullOrEmpty(traceId))
                    {
                        traceId = Guid.NewGuid().ToString();
                        httpContext.Request.Headers[AppSettingManager.TRANCEID] = traceId;
                    }
                    userId = httpContext.Request.Headers[AppSettingManager.USERID];
                    remoteIp = httpContext?.Connection.RemoteIpAddress.ToString();
                }
                if (!objs.Any(p => p.Key == AppSettingManager.TRANCEID)) objs = objs.Append(new KeyValuePair<string, object>(AppSettingManager.TRANCEID, traceId)).ToArray();
                if (!objs.Any(p => p.Key == AppSettingManager.USERID)) objs = objs.Append(new KeyValuePair<string, object>(AppSettingManager.USERID, userId)).ToArray();
                if (!objs.Any(p => p.Key == AppSettingManager.REMOTEIP)) objs = objs.Append(new KeyValuePair<string, object>(AppSettingManager.REMOTEIP, remoteIp)).ToArray();
            }
            return objs;
        }
    }
}
